package tech.veedo.munchkin.services.backend.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tech.veedo.munchkin.beans.backend.Node;
import tech.veedo.munchkin.constants.Operation;
import tech.veedo.munchkin.mappers.backend.NodeMapper;
import tech.veedo.munchkin.services.backend.NodeService;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class NodeServiceImpl extends ServiceImpl<NodeMapper, Node> implements NodeService {

    @Override
    @Transactional
    public boolean saveNode(Node node) {
        // 创建待插入的审核节点
        Node forInsert = new Node()
                .setVersion(1L)
                .setName(node.getName())
                .setMappingID(node.getMappingID())
                .setAllchecked(node.isAllchecked());

        // 获取所在mapping内的所有节点
        QueryWrapper<Node> wrapper = new QueryWrapper<>();
        wrapper.eq("mapping_id", forInsert.getMappingID())
                .orderByDesc("sort");
        List<Node> nodes = list(wrapper);
        // 如果所在mapping没有节点，则sort强制为1
        if (CollectionUtils.isEmpty(nodes)) {
            forInsert.setSort(1);
        // 如果所在mapping有节点:
        } else {
            // 获取sort当前的最大值
            Integer max = nodes.get(0).getSort();
            if (max==Integer.MAX_VALUE) {
                throw new IllegalStateException("当前节点顺序最大值已超出范围，请联系管理员重新排列赋值");
            }
            // 则：1：新增node如果没有sort值或大于当前max，强制sort = max+1
            if (ObjectUtils.isEmpty(node.getSort()) || node.getSort() > max) {
                forInsert.setSort(max+1);
            // 2: 新增node的sort值在<=max范围，则右侧节点顺移1；
            } else {
                forInsert.setSort(node.getSort());
                baseMapper.sortShiftRight1(forInsert.getMappingID(), forInsert.getSort());
            }
        }
        return save(forInsert);
    }

    @Override
    @Transactional
    public boolean updateNode(Node node) {
        // 查询mapping更新策略  --废弃
        // code here...  --废弃
        Node fromDB = getById(node.getId());
        if (ObjectUtils.isEmpty(fromDB)) {
            throw new NullPointerException("审核节点为空或者已被删除");
        }
        if (!Objects.equals(fromDB.getVersion(), node.getVersion())) {
            throw new IllegalStateException("审核节点已经更新，请刷新");
        }

        // 改变name, allchecked, sort
        Node forUpdate = new Node().setName(node.getName());
        forUpdate.setId(node.getId());

        // allchecked
        if (fromDB.isAllchecked() != node.isAllchecked()) {
            // 全部审批通过 =》 一人审批通过即可
            if (fromDB.isAllchecked()) {
                // 查看node的审批关系，然后如果有审批通过的，就通过
                // code here...

            }
        }

        // sort
        if (ObjectUtils.isNotEmpty(node.getSort())) {
            // 处理一下sort
            // 获取sort当前的最大值
            QueryWrapper<Node> wrapper = new QueryWrapper<>();
            wrapper.eq("mapping_id", fromDB.getMappingID())
                    .orderByDesc("sort");
            List<Node> nodes = list(wrapper);
            if (nodes.size() == 1) {
                // 只有一个节点，则修改的也是这个节点；
                forUpdate.setSort(node.getSort());
            } else {
                Integer max = list(wrapper).get(0).getSort();
                if (max==Integer.MAX_VALUE) {
                    throw new IllegalStateException("当前节点顺序最大值已超出范围，请联系管理员重新排列赋值");
                }
                // 1：node的sort大于当前max，强制sort = max+1
                if (node.getSort() > max) {
                    forUpdate.setSort(max+1);
                    // 2: node的sort值在<=max范围，则右侧节点顺移1；
                } else {
                    forUpdate.setSort(node.getSort());
                    baseMapper.sortShiftRight1(fromDB.getMappingID(), forUpdate.getSort());
                }
            }
        }

        return updateById(forUpdate);
    }

    @Override
    @Transactional
    public boolean deleteNode(Long id) {
        // 查看节点下是否有待审核的数据，如果有，不允许删除
        // code here...

        return removeById(id);
    }

    @Override
    public List<Node> chain(Long mappingid) {
        QueryWrapper<Node> wrapper = new QueryWrapper<>();
        wrapper.eq("mapping_id", mappingid)
                .orderByAsc("sort");
        return list(wrapper);
    }

}
